#include "si24r1.h"

/****************************SPI*********************************/
void MySPI_Init(void)
{
	MySPI_W_CSN(1);
	MySPI_W_SCK(0);
}

void MySPI_Start(void)
{
	MySPI_W_CSN(0);
}

void MySPI_Stop(void)
{
	MySPI_W_CSN(1);
}

static uint8_t SPI_RW(uint8_t byte)
{
	uint8_t bit_ctr;
	for(bit_ctr=0; bit_ctr<8; bit_ctr++)
	{
		if(byte & 0x80)
			MOSI(1);
		else
			MOSI(0);																 
		byte = (byte << 1);                      
		SCK(1);                                   
		byte |= MISO;                             
		SCK(0);                                
	}
	return(byte);                              
}

/***********************SI24R1*********************************/
//const uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x0A,0x01,0x07,0x0E,0x11};
uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x00, 0x00, 0x00, 0x00, 0x11};
void SI24R1_Init(void)
{
	MySPI_Init();
	SCK(0); 
	CSN(1);				
	CE(0);				
	//IRQ();
	TX_ADDRESS[0] = *(volatile uint16_t*)0x08003800;
	TX_ADDRESS[1] = *(volatile uint16_t*)0x08003802;
	TX_ADDRESS[2] = *(volatile uint16_t*)0x08003804;
	TX_ADDRESS[3] = *(volatile uint16_t*)0x08003806;
	TX_ADDRESS[4] = *(volatile uint16_t*)0x08003808;
}

uint8_t SI24R1_Write_Reg(uint8_t reg, uint8_t value)
{
	uint8_t status;
	CSN(0);                 
	status = SPI_RW(reg);				
	SPI_RW(value);
	CSN(1);  
	return(status);
}

uint8_t SI24R1_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes)
{
	uint8_t status,byte_ctr;
	CSN(0);                                  			
	status = SPI_RW(reg);                          
	for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)     
		SPI_RW(*pBuf++);
	CSN(1);                                      	
	return(status);       
}							  					   

uint8_t SI24R1_Read_Reg(uint8_t reg)
{
 	uint8_t value;
	CSN(0);    
	SPI_RW(reg);			
	value = SPI_RW(0);
	CSN(1);              
	return(value);
}

uint8_t SI24R1_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{
	uint8_t status,byte_ctr;

  CSN(0);                                        
  status = SPI_RW(reg);                           
  for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    pBuf[byte_ctr] = SPI_RW(0);	
  CSN(1);                                        

  return(status);    
}



void SI24R1_RX_Mode(void)
{
	CE(0);
	SI24R1_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
	SI24R1_Write_Reg(WRITE_REG + RX_PW_P0, 32);
	SI24R1_Write_Reg(WRITE_REG + EN_AA, 0x01);
	SI24R1_Write_Reg(WRITE_REG + EN_RXADDR, 0x01);
	SI24R1_Write_Reg(WRITE_REG + SETUP_RETR, 0x0a);
	SI24R1_Write_Reg(WRITE_REG + RF_CH, 40);  
	SI24R1_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);
	SI24R1_Write_Reg(WRITE_REG + CONFIG, 0x0f);
	CE(1);
	//Delay_10ms(1);
}						

void tx_package_mode(uint8_t *tx_buf)
{
	CE(0);
	SI24R1_Write_Reg(FLUSH_TX,0xff);
	SI24R1_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);		//写入发送地址
	SI24R1_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);		//为了应答接收设备，接收通道0地址与发送地址相同
	SI24R1_Write_Buf(WR_TX_PLOAD, tx_buf, 32);								//直接写入数据（这个型号只能这么弄，不知道为什么）
	SI24R1_Write_Reg(WRITE_REG + RX_PW_P0, 32); 							//接收通道0选择与发送通道相同的有效数据宽度
	SI24R1_Write_Reg(WRITE_REG + EN_AA, 0x01); 								//使能接收通道0自动应该
	SI24R1_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); 							//使能接收通道0
	SI24R1_Write_Reg(WRITE_REG + SETUP_RETR, 0x0a); 						//自动重发
	SI24R1_Write_Reg(WRITE_REG + RF_CH, 40); 								//选择射频通道40
	SI24R1_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);							//数据传输功率2Mbps,发射功率7dbm
	SI24R1_Write_Reg(WRITE_REG + CONFIG, 0x0e);								//CRC使能，16位CRC校验，上电
	SI24R1_Write_Reg(WRITE_REG + STATUS, 0xff);
	CE(1);	
}
extern uint8_t state_tx_flag ;
uint8_t tx_package(uint8_t* tx_buf)
{
	tx_package_mode(tx_buf);
	uint32_t i = 65536;
	while(IRQ == 1)	
	{
		i--;
		if(i == 53000) break;
	}
	uint8_t stateT = SI24R1_Read_Reg(STATUS);
	state_tx_flag = stateT;
	if(stateT & 0x20)
	{
		SI24R1_Write_Reg(READ_REG+STATUS, stateT);
		return 0x20;
	}
	if(stateT & MAX_RT)
	{
		SI24R1_Write_Reg(READ_REG+STATUS, stateT);
		SI24R1_Write_Reg(FLUSH_TX,0xff);
		return 0x10;
	}
	return 0xff;
}


/**
 * Function: SI24R1_RxPacket
 * Description: SI24R1接收数据函数
 * input param: rxbuf:接收数据的首地址
 * return param: 0:接收到数据，1:没有接收到数据
 */
uint8_t SI24R1_RxPacket(uint8_t *rxbuf)
{
	uint8_t stateR = 0;
	uint8_t pload_width;
	if(IRQ == 0)
	{
		stateR = SI24R1_Read_Reg(STATUS);	//读取状态寄存器
		SI24R1_Write_Reg(WRITE_REG+STATUS,stateR);
		if(stateR & 0x40)//接收到数据
		{
			pload_width = SI24R1_Read_Reg(0x60);
			SI24R1_Read_Buf(RD_RX_PLOAD,rxbuf,pload_width);
			SI24R1_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO
			return 0; 
		}	
	}
	SI24R1_Write_Reg(FLUSH_RX,0xff);
	return 1; 
}

/**
 * Function: SI24R1_Check
 * Description: 检测SI24R1是否正常工作
 * input param: 无
 * return param: 0：正常工作，1：不正常工作
 */
uint8_t SI24R1_Check(void)
{
	uint8_t buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
	uint8_t i;
	SI24R1_Write_Buf(WRITE_REG + TX_ADDR, buf, TX_ADR_WIDTH); 
	buf[0] = 0;buf[1] = 0;buf[2] = 0;buf[3] = 0;buf[4] = 0;
	SI24R1_Read_Buf(TX_ADDR,buf,5);
	for(i=0;i<5;i++)if(buf[i]!=0XA5)break;	 							   
	if(i!=5)return 1;	
	return 0;
}


